﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

// 管理生命体的技能
// 每一个生命体，都拥有自己的实例
public class SkillMgr
{
    private Creature _owner;

    // 施法器
    private SkillCaster _skillCaster = new SkillCaster();

    // 技能逻辑对象列表
    private List<CreatureSkill> _skillLogicList = new List<CreatureSkill>();

    // 技能辅助模块
    private SkillAssist _skillAssist = new SkillAssist();

    private CDMgr _cdMgr = new CDMgr();

    public bool IsCastingSkill
    {
        get { return _skillCaster.IsCastingSkill; }
    }

    // 当重新选择了目标时，回调
    public Action<Creature> ReSelectTargetCallback;

    public void Init(Creature owner)
    {
        _owner = owner;
        _skillCaster.Init(_owner);
        _skillAssist.Init(_owner);

        foreach (var skillid in _owner.TableData.SkillList)
        {
            // 静态的表格数据
            var skillData = SkillTable.Instance[skillid];
            // 动态的逻辑数据
            var skillLogic = typeof(SkillLogicBase).Assembly.CreateInstance(skillData.ScriptType) as SkillLogicBase;
            // 静态、动态打包
            var skillObj = new CreatureSkill() { Data = skillData, Logic = skillLogic };
            // 初始化动态数据
            skillLogic.Init(_owner, skillObj, _cdMgr);

            _skillLogicList.Add(skillObj);
        }
    }

    public void CastSkill(int index)
    {
        // 如果有技能正在施放，无视当前施法请求
        if (_skillCaster.IsCastingSkill)
        {
            Debug.Log("技能提示：正在放技能");
            return;
        }

        var skillObj = _skillLogicList[index];
        if (skillObj == null)
        {
            Debug.LogError("未找到技能对象，索引号：" + index);
            return;
        }

        // 该技能在CD中，不能释放
        if (skillObj.Logic.IsInCD)
        {
            Debug.LogError("技能在CD中，剩余时间：" + skillObj.Logic.LeftCD);
            return;
        }

        // 该技能需要目标
        if (skillObj.Data.CastRange > 0)
        {
            // 自动选择目标
            var oldTarget = _owner.CurTarget;
            _owner.CurTarget = _skillAssist.AutoSelectTarget(_owner.CurTarget);
            // 如果附近没有可攻击目标
            if (_owner.CurTarget == null ||
                !_owner.CurTarget.CanBeAttack(_owner))
            {
                Debug.Log("技能提示：附近没有可攻击目标");
                return;
            }

            // 是否重新选择了目标
            if (oldTarget != _owner.CurTarget)
            {
                if (ReSelectTargetCallback != null)
                {
                    ReSelectTargetCallback(_owner.CurTarget);
                }
            }

            var dis =
                _owner.Position.Distance25D(_owner.CurTarget.Position);
            if (dis > skillObj.Data.CastRange)
            {
                _owner.TraceTo(_owner.CurTarget, skillObj.Data.CastRange,
                    () => CastSkill(index));
                return;
            }
        }

        Debug.Log("正常放技能：" + index);
        // 施放技能
        _skillCaster.CastSkill(skillObj.Logic, _owner.CurTarget);
    }

    internal float GetLeftCD(int index)
    {
        var skillObj = _skillLogicList[index];
        if (skillObj == null)
        {
            //Debug.LogError("未找到技能对象，索引号：" + index);
            return 0;
        }

        return skillObj.Logic.LeftCD;
    }

    internal float GetMaxCD(int index)
    {
        var skillObj = _skillLogicList[index];
        if (skillObj == null)
        {
            //Debug.LogError("未找到技能对象，索引号：" + index);
            return 0;
        }

        return skillObj.Logic.MaxCD;
    }

    public void Loop()
    {
        _skillCaster.Loop();
    }
}

// 技能的静态数据、动态数据打包
public class CreatureSkill
{
    public SkillTableData Data;
    public SkillLogicBase Logic;
}

